package com.smart.community.commons.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;

/**
 * 数据源监控配置
 * @author Wu.Liang
 * @since 2024-12-19
 * @version 1.0.0
 */
@Slf4j
@Configuration
@EnableScheduling
@ConditionalOnProperty(name = "smart.community.datasource.monitor.enabled", havingValue = "true", matchIfMissing = true)
public class DataSourceMonitorConfig {
    
    /**
     * 数据源监控器
     * 
     * @param dataSource 数据源
     * @return 数据源监控器
     */
    @Bean
    public DataSourceMonitor dataSourceMonitor(DataSource dataSource) {
        return new DataSourceMonitor(dataSource);
    }
    
    /**
     * 数据源监控器内部类
     */
    public static class DataSourceMonitor {
        
        private final DataSource dataSource;
        
        public DataSourceMonitor(DataSource dataSource) {
            this.dataSource = dataSource;
        }
        
        /**
         * 检查数据源连接状态
         * 
         * @return 连接是否正常
         */
        public boolean checkConnection() {
            try (Connection connection = dataSource.getConnection()) {
                boolean isValid = connection.isValid(5);
                if (isValid) {
                    log.debug("✅ 数据源连接正常");
                } else {
                    log.warn("⚠️ 数据源连接异常");
                }
                return isValid;
            } catch (SQLException e) {
                log.error("❌ 数据源连接失败", e);
                return false;
            }
        }
        
        /**
         * 获取数据源信息
         * 
         * @return 数据源信息
         */
        public DataSourceInfo getDataSourceInfo() {
            DataSourceInfo info = new DataSourceInfo();
            
            try (Connection connection = dataSource.getConnection()) {
                info.setUrl(connection.getMetaData().getURL());
                info.setDatabaseProductName(connection.getMetaData().getDatabaseProductName());
                info.setDatabaseProductVersion(connection.getMetaData().getDatabaseProductVersion());
                info.setDriverName(connection.getMetaData().getDriverName());
                info.setDriverVersion(connection.getMetaData().getDriverVersion());
                info.setConnected(true);
                
                log.debug("📊 数据源信息: {}", info);
            } catch (SQLException e) {
                log.error("❌ 获取数据源信息失败", e);
                info.setConnected(false);
            }
            
            return info;
        }
        
        /**
         * 数据源信息
         */
        public static class DataSourceInfo {
            private String url;
            private String databaseProductName;
            private String databaseProductVersion;
            private String driverName;
            private String driverVersion;
            private boolean connected;
            
            // Getters and Setters
            public String getUrl() { return url; }
            public void setUrl(String url) { this.url = url; }
            
            public String getDatabaseProductName() { return databaseProductName; }
            public void setDatabaseProductName(String databaseProductName) { this.databaseProductName = databaseProductName; }
            
            public String getDatabaseProductVersion() { return databaseProductVersion; }
            public void setDatabaseProductVersion(String databaseProductVersion) { this.databaseProductVersion = databaseProductVersion; }
            
            public String getDriverName() { return driverName; }
            public void setDriverName(String driverName) { this.driverName = driverName; }
            
            public String getDriverVersion() { return driverVersion; }
            public void setDriverVersion(String driverVersion) { this.driverVersion = driverVersion; }
            
            public boolean isConnected() { return connected; }
            public void setConnected(boolean connected) { this.connected = connected; }
            
            @Override
            public String toString() {
                return String.format("DataSourceInfo{url='%s', database='%s %s', driver='%s %s', connected=%s}",
                        url, databaseProductName, databaseProductVersion, driverName, driverVersion, connected);
            }
        }
    }
}
